
/*
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include <stdio.h>
#include <string.h>

#include "libmooigraph.h"
#include "lmg.h"

char *
lmg_version (void)
{
  return ((char *) "1.9");
}

void
lmg_debug (int on_off)
{
  if (on_off)
    {
      lmgdebug = 1;
    }
  else
    {
      lmgdebug = 0;
    }
  return;
}

void
lmg_init (void)
{
  if (lmgdebug)
    {
      printf ("%s(): malloc count is %d\n", __FUNCTION__, lmgmalloccount);
    }
  lmg_deinit ();
  if (lmgdebug)
    {
      printf ("%s():   free count is %d\n", __FUNCTION__, lmgfreecount);
    }
  lmgmalloccount = 0;
  lmgfreecount = 0;
  lmgnrealnodes = 0;
  lmgnrealedges = 0;
  lmgedgelabelcount = 0;
  return;
}

void
lmg_deinit (void)
{
  lmg_uniqsclear ();
  lmg_uniqnclear ();
  lmg_connectclear ();
  lmg_nodelistclear ();
  lmg_edgelistclear ();
  lmg_levelsclear ();
  lmg_barycenterclear ();
  return;
}

void
lmg_addnode (char *name)
{
  struct lmgnode *node;
  if (!name)
    {
      return;
    }
  node = lmg_uniqn (name);
  if (node)
    {
      return;
    }
  node = lmg_malloc (sizeof (struct lmgnode));
  node->name = name;
  lmg_uniqnadd (name, node);
  lmg_nodelistadd (node);
  if (lmgdebug)
    {

    }
  if (lmgdebug)
    {
      printf ("%s(): added node '%s'\n", __FUNCTION__, name);
    }
  lmgnrealnodes = lmgnrealnodes + 1;
  return;
}

void
lmg_addedge (char *from, char *to, char *label, int color, int style,
	     int textcolor, int fontsize, char *fontname, int bold,
	     int italic, int oblique)
{
  struct lmgnode *fromnode;
  struct lmgnode *tonode;
  struct lmgnode *elnode;
  char buf[32];
  char *edgelabelname = NULL;
  if (!from)
    {
      return;
    }
  if (!to)
    {
      return;
    }
  fromnode = lmg_uniqn (from);
  if (!fromnode)
    {
      lmg_addnode (from);
      fromnode = lmg_uniqn (from);
    }
  tonode = lmg_uniqn (to);
  if (!tonode)
    {
      lmg_addnode (to);
      tonode = lmg_uniqn (to);
    }
  if (label)
    {
      memset (buf, 0, 32);
      snprintf (buf, 32 - 1, "___lmgedgelabel%d___", lmgedgelabelcount);
      lmgedgelabelcount = lmgedgelabelcount + 1;
      edgelabelname = lmg_uniqs (buf);
      lmg_addnode (edgelabelname);
      elnode = lmg_uniqn (edgelabelname);
      elnode->label = label;
      elnode->textcolor = textcolor;
      elnode->fontsize = fontsize;
      elnode->fontname = fontname;
      elnode->bitflags.edgelabel = 1;
      if (bold)
	{
	  elnode->bitflags.textbold = 1;
	}
      if (italic)
	{
	  elnode->bitflags.textitalic = 1;
	}
      if (oblique)
	{
	  elnode->bitflags.textoblique = 1;
	}
    }
  if (label)
    {
      lmg_edgelistadd (fromnode, elnode, color, style);
      lmgnrealedges = lmgnrealedges + 1;
      lmg_edgelistadd (elnode, tonode, color, style);
      lmgnrealedges = lmgnrealedges + 1;
    }
  else
    {
      lmg_edgelistadd (fromnode, tonode, color, style);
      lmgnrealedges = lmgnrealedges + 1;
    }
  if (lmgdebug)
    {
      printf ("%s(): added edge from '%s' to '%s' label '%s'\n", __FUNCTION__,
	      from, to, label);
    }
  return;
}

void
lmg_main (void)
{
  lmg_selfedges ();
  lmg_inout ();
  lmg_cycles ();
  lmg_dfs ();
  lmg_splitedges ();
  lmg_connect ();
  lmg_levels ();
  lmg_barycenter ();
  return;
}

int
lmg_nlevels (void)
{
  return (lmgnlevels);
}

int
lmg_nal (int level)
{
  return (lmg_nnal (level));
}

int
lmg_nnodes (void)
{
  struct lmgnodel *ptr;
  int n;
  ptr = lmgnodelist;
  n = 0;
  while (ptr)
    {
      n = n + 1;
      if (ptr->next == NULL)
	{
	  break;
	}
      ptr = ptr->next;
    }
  return (n);
}

int
lmg_ndummynodes (void)
{
  struct lmgnodel *ptr;
  int n;
  ptr = lmgnodelist;
  n = 0;
  while (ptr)
    {
      if (ptr->node->name == NULL)
	{
	  n = n + 1;
	}
      if (ptr->next == NULL)
	{
	  break;
	}
      ptr = ptr->next;
    }
  return (n);
}

int
lmg_nedges (void)
{
  struct lmgedgel *el;
  int n;
  el = lmgedgelist;
  n = 0;
  while (el)
    {
      n = n + 1;
      if (el->next == NULL)
	{
	  break;
	}
      el = el->next;
    }
  return (n);
}

int
lmg_nrevedges (void)
{
  struct lmgedgel *el;
  int n;
  el = lmgedgelist;
  n = 0;
  while (el)
    {
      if (el->edge->bitflags.reversed == 1)
	{
	  n = n + 1;
	}
      if (el->next == NULL)
	{
	  break;
	}
      el = el->next;
    }
  return (n);
}

int
lmg_ncrossings (void)
{
  return lmg_crossings ();
}

struct lmgnodel *
lmg_nodehead (int level)
{
  if (level == -1)
    {
      return (lmgnodelist);
    }
  return (lmglevels[level]);
}

struct lmgedgel *
lmg_edgehead (void)
{
  return (lmgedgelist);
}

int
lmg_nrealnodes (void)
{
  return (lmgnrealnodes);
}

int
lmg_nrealedges (void)
{
  return (lmgnrealedges);
}


/* End */
